import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import java.util.StringTokenizer;

import javax.servlet.http.*;  // provides servlet functionality
import javax.servlet.*;	      // ditto
import javax.*;

public class CustomerInformation extends HttpServlet {
	
	private final static String REDIRECT_TO_LOGIN_CODE 
		= "<meta http-equiv=\"REFRESH\" content=\"2;url=../Login.jsp\">";
	
	public void doGet(HttpServletRequest request, HttpServletResponse response)
	throws IOException, ServletException
	{
		doPost(request, response);
	}
	
	public void doPost(HttpServletRequest request, HttpServletResponse response)
	throws IOException, ServletException
	{
		if (!Bridge.hasBeenToMainPage(request.getSession(), response.getWriter()))
		{
			return;
		}
		
		System.out.println("---Doing Post in CustomerInformation---\n");
		
		PrintWriter out = response.getWriter();
		ArrayList<DVD> dvds = new ArrayList<DVD>();
		CartOfItems cart;
		
		HttpSession session = request.getSession();
		
		StringBuffer body = new StringBuffer("");
		
		boolean customerInfoValid = true;
		
		String newCreditCardNumber = request.getParameter("CC_NUM");
		String newCreditCardHolder = request.getParameter("CC_HOLDER");
		String newExpirationDate = request.getParameter("CC_DATE");
		String newAddress = request.getParameter("ADDR");
		String newShippingAddress = request.getParameter("SHIP_ADDR");
		
		System.out.println("new Date=[" + newExpirationDate + "]");
		
		boolean updatingCreditCardNumber = (newCreditCardNumber != null && !newCreditCardNumber.equals(""));
		boolean updatingCreditCardHolder = (newCreditCardHolder != null && !newCreditCardHolder.equals(""));
		boolean updatingExpirationDate = (newExpirationDate != null && !newExpirationDate.equals(""));
		boolean updatingAddress = (newAddress != null && !newAddress.equals(""));
		boolean updatingShippingAddress = (newShippingAddress != null && !newShippingAddress.equals(""));			
			
		boolean newCCNvalid = false;
		if (updatingCreditCardNumber)
		{	
			if(newCreditCardNumber.length() > 16 || newCreditCardNumber.length() < 15 
					|| !isNumber(newCreditCardNumber.substring(0, 8)) || !isNumber(newCreditCardNumber.substring(8)) )
				newCCNvalid = false;
			else
				newCCNvalid = true;
		}
		
		boolean newDateValid = false;		
		String month = null;
		String day = null;
		String year = null;
		
		if (updatingExpirationDate )
		{
			StringTokenizer st = new StringTokenizer(newExpirationDate, "-");
			
			if (st.hasMoreTokens())
				year = st.nextToken();
			if (st.hasMoreTokens())
				month = st.nextToken();
			if (st.hasMoreTokens())
				day = st.nextToken();
			
			
			/*	1		2			3		 4			5		6
			 * jan 31   feb 28/29   mar 31   apr 30   may 31   jun 30
			 * 7		8		  9		   10		11		12
			 * jul 31   aug 31   sep 30   oct 31   nov 30   dec 31
			 * 
			 */
			if (day != null && isNumber(month) && isNumber(day) && isNumber(year) )
			{
				int monthNum = Integer.parseInt(month);
				int dayNum = Integer.parseInt(day);
				int yearNum = Integer.parseInt(year);
				if (yearNum >= 1900 && dayNum >= 1 && 
						((monthNum == 1 || monthNum == 3 || monthNum == 5 || monthNum == 7
							|| monthNum == 8 || monthNum == 10 || monthNum == 12) && dayNum <= 31  ||
						(monthNum == 4 || monthNum == 6 || monthNum == 9 || monthNum == 11) && dayNum <= 30 ||
						monthNum == 2 && dayNum <= 29)
					)
					newDateValid = true;
			}
		}
		
		java.sql.Date newDate = null;
		if (newDateValid)
			newDate = new java.sql.Date(Integer.parseInt(year) - 1900, Integer.parseInt(month) - 1, Integer.parseInt(day) );
		
		System.out.println("newDate (the one to store)=[" + newDate + "]");
		
		if (newShippingAddress != null && !newShippingAddress.equals(""))
			session.setAttribute(Constants.shippingAddressAttributeName, newShippingAddress);
		
		Enumeration<String> paramNames = request.getParameterNames();
		while (paramNames.hasMoreElements())
		{
			String paramName = paramNames.nextElement();
			System.out.println(paramName + "=" + request.getParameter(paramName));
		}
				
		try
		{
			Class.forName("org.postgresql.Driver").newInstance();
			Connection connection = DriverManager.getConnection(
				"jdbc:postgresql://localhost/fabflixs", "testuser", "testpass");	
			
			String user = (String)session.getAttribute(Constants.loggedInUserAttributeName);
			if (user == null)
			{
				// the user needs to log in first!
				out.print("<html><head><title>Redirecting...</title>"
						+ REDIRECT_TO_LOGIN_CODE + "</head>"
						+ "<body>You need to log in first...</body>" 
						+"</html>");
				return;
			}
			
			Statement select = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
			ResultSet resultThisCustomer = select.executeQuery("Select * from customers WHERE email = \'" + user + "\'");
			
			int creditCardId = 0;
			
			//get info for the customer
			if (resultThisCustomer.next())
			{
				if (updatingAddress)
				{
					resultThisCustomer.updateString("address", newAddress);
					resultThisCustomer.updateRow();
				}
				
				String firstName = resultThisCustomer.getString(2);
				String lastName = resultThisCustomer.getString(3);
				String address = resultThisCustomer.getString(5);
				String shippingAddress = (String) session.getAttribute(Constants.shippingAddressAttributeName);
				
				if (shippingAddress == null )
				{
					shippingAddress = address;
					session.setAttribute(Constants.shippingAddressAttributeName, shippingAddress);
				}
				
				body.append(firstName + " " + lastName + ", here is the information we have on file for you:<br>");				
				
				creditCardId = resultThisCustomer.getInt(4);				
				Statement select2 = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
				ResultSet result2 = select2.executeQuery("Select * from creditcards WHERE id = \'" + creditCardId + "\'");
				
				//get info for the customer's credit card
				String creditCardNumber = null;
				String creditCardHolder = null;
				Date expirationDate = null;
				boolean cardExpired = true;
				if (result2.next())
				{
					if (updatingCreditCardNumber && newCCNvalid)
					{
						result2.updateString("credit_card_number", newCreditCardNumber);
						result2.updateRow();
					}
					
					if (updatingCreditCardHolder)
					{
						result2.updateString("name_on_card", newCreditCardHolder);
						result2.updateRow();
					}
					
					if (updatingExpirationDate && newDateValid)
					{
						result2.updateDate("expiration", newDate);
						result2.updateRow();
					}
					
					creditCardNumber = result2.getString(1);
					creditCardHolder = result2.getString(2);
					expirationDate = result2.getDate(3);
					
					System.out.println("Date retrieved from database=[" + expirationDate + "]");
										
					Calendar expirationCal = Calendar.getInstance();
					expirationCal.setTime(expirationDate);
					Calendar currentCal = Calendar.getInstance();
					cardExpired = (expirationCal.compareTo(currentCal) < 0);
					
					System.out.println("creditCardNumber=" + creditCardNumber);
					System.out.println("creditCardHolder=" + creditCardHolder);
					System.out.println("expirationDate=" + expirationDate);
					System.out.println("address=" + address);
					System.out.println("shippingAddress=" + shippingAddress);
					
					customerInfoValid &= creditCardNumber != null && !creditCardNumber.equals("");
					customerInfoValid &= creditCardHolder != null && !creditCardHolder.equals("");
					customerInfoValid &= !cardExpired && expirationDate != null && !expirationDate.equals("");
					customerInfoValid &= address != null && !address.equals("");
					customerInfoValid &= shippingAddress != null && !shippingAddress.equals("");
					
					session.setAttribute(Constants.customerInfoGoodAttributeName, new Boolean(customerInfoValid));
				}
				else //insert the credit card, if the user is trying to do so
				{
					Statement select3 = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
					Statement select4 = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
					Statement select5 = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
					ResultSet resultMaxCreditCardId = select3.executeQuery("Select max(id) from creditcards");
					ResultSet resultCreditCards = select4.executeQuery("Select * from creditcards");
										
					resultMaxCreditCardId.next();
					int newCCid = resultMaxCreditCardId.getInt(1) + 1;
					
					if (updatingCreditCardNumber && newCCNvalid && updatingCreditCardHolder 
							&& updatingExpirationDate && newDateValid)
					{					
						resultCreditCards.moveToInsertRow();
						resultCreditCards.updateInt("id", newCCid);
						resultCreditCards.updateString("credit_card_number", newCreditCardNumber);
						resultCreditCards.updateString("name_on_card", newCreditCardHolder);
						resultCreditCards.updateDate("expiration", newDate);
						resultCreditCards.insertRow();
						
						resultThisCustomer.updateInt("cc_id", newCCid);
						resultThisCustomer.updateRow();
						
						doPost(request, response);
						return;
					}
					else
					{
						customerInfoValid = false;
					}				
				}
					
				body.append("<form name=\"updateCustomerForm\" action=\"CustomerInformation\" method=\"POST\">");
				body.append("<TABLE border=\"0\">");
				
				body.append("<TR>");
				body.append("<TD>");
				body.append("<div align=\"right\"></div>");
				body.append("</TD>");
				body.append("<TD>");
				body.append("<div align=\"left\"><b><u>On file info</u></b></div>");
				body.append("</TD>");
				body.append("<TD>");
				body.append("<div><b>Update Info<br><u>(if needed)</u></b></div>");
				body.append("</TD>");
				body.append("</TR>");
				
				body.append("<TR>");
				body.append("<TD>");
				body.append("<div align=\"right\">Credit Card Number:</div>");
				body.append("</TD>");
				body.append("<TD>");
				if (creditCardNumber == null)
					body.append("<div align=\"left\"><i>Unknown.</i></div>");
				else
					body.append("<div align=\"left\">" + creditCardNumber + "</div>");
				body.append("</TD>");
				body.append("<TD>");
				body.append("<input name=\"CC_NUM\" type=\"text\">" );
				body.append("</TD>");
				body.append("<TD>");
				if (creditCardNumber == null)
					body.append("<div align=\"left\"><font color=\"red\">No card on file. Please enter card number.</font></div>");
				else if (updatingCreditCardNumber && !newCCNvalid)
					body.append("<div align=\"left\"><font color=\"red\">The number you entered was not valid.</font></div>");
				else if (updatingCreditCardNumber && newCCNvalid)
					body.append("<div align=\"left\"><font color=\"blue\">Number updated.</font></div>");
				body.append("</TD>");
				body.append("<TD rowspan=\"5\">");					
				body.append("<input type=\"image\" name=\"UpdateInfoButton\" src=\"../images/Update.png\">");
				body.append("</TD>");
				body.append("</TR>");
				
				body.append("<TR>");
				body.append("<TD>");
				body.append("<div align=\"right\">Credit Card Holder:</div>");
				body.append("</TD>");
				body.append("<TD>");
				if (creditCardHolder == null)
					body.append("<div align=\"left\"><i>Unknown.</i></div>");
				else
					body.append("<div align=\"left\">" + creditCardHolder + "</div>");
				body.append("</TD>");
				body.append("<TD>");
				body.append("<input name=\"CC_HOLDER\" type=\"text\">" );
				body.append("</TD>");
				body.append("<TD>");
				if (creditCardHolder == null)
					body.append("<div align=\"left\"><font color=\"red\">Please enter card holder's name.</font></div>");
				else if (updatingCreditCardHolder)
					body.append("<div align=\"left\"><font color=\"blue\">Credit card holder updated.</font></div>");
				body.append("</TD>");
				body.append("</TR>");
				
				body.append("<TR>");				
				body.append("<TD>");
				body.append("<div align=\"right\">Expiration Date:</div>");
				body.append("</TD>");
				body.append("<TD>");
				if (expirationDate == null)
					body.append("<div align=\"left\"><i>Unknown.</i></div>");
				else if (updatingExpirationDate && newDate != null )
					body.append("<div align=\"left\">" + newDate + "</div>");
				else
					body.append("<div align=\"left\">" + expirationDate + "</div>");
				body.append("</TD>");				
				body.append("<TD>");
				body.append("<input name=\"CC_DATE\" type=\"text\">" );
				body.append("</TD>");
				body.append("<TD>");
				if (expirationDate == null)
					body.append("<div align=\"left\"><font color=\"red\">Please enter card's expiration date. (yyyy-mm-dd)</font></div>");
				else if (!newDateValid && updatingExpirationDate)
					body.append("<div align=\"left\"><font color=\"red\"><b>The date you entered was invalid.<br>Please follow this format: (yyyy-mm-dd)</b></font></div>");
				else if (cardExpired)
					body.append("<div align=\"left\"><font color=\"red\"><b>" +
						"Your card is expired. Please update<br>its expiration date. (yyyy-mm-dd)" +
						"</b></font></div>");
				else if (updatingExpirationDate)
					body.append("<div align=\"left\"><font color=\"blue\">Expiration date updated. (yyyy-mm-dd)</font></div>");
				else
					body.append("<div align=\"left\"><font color=\"black\">(yyyy-mm-dd).</font></div>");				
				body.append("</TD>");
				body.append("</TR>");
				
				body.append("<TR>");
				body.append("<TD>");
				body.append("<div align=\"right\">Address:</div>");
				body.append("</TD>");
				body.append("<TD>");
				if (address == null)
					body.append("<div align=\"left\"><i>Unknown.</i></div>");
				else
					body.append("<div align=\"left\">" + address + "</div>");
				body.append("</TD>");
				body.append("<TD>");
				body.append("<input name=\"ADDR\" type=\"text\">" );
				body.append("</TD>");
				body.append("<TD>");
				if (address == null)
					body.append("<div align=\"left\"><font color=\"red\">Please enter your address.</font></div>");
				else if (updatingAddress)
					body.append("<div align=\"left\"><font color=\"blue\">Your address has been updated.</font></div>");
				body.append("</TD>");
				body.append("</TR>");
				
				body.append("<TR>");
				body.append("<TD>");
				body.append("<div align=\"right\">Shipping Address:</div>");
				body.append("<TD>");
				if (shippingAddress == null)
					body.append("<div align=\"left\"><i>Unknown.</i></div>");
				else
					body.append("<div align=\"left\">" + shippingAddress + "</div>");
				body.append("</TD>");
				body.append("<TD>");
				body.append("<input name=\"SHIP_ADDR\" type=\"text\">" );
				body.append("</TD>");		
				body.append("<TD>");
				if (!updatingShippingAddress)
					body.append("<div align=\"left\"><font color=\"black\">(if different)</font></div>");
				else
					body.append("<div align=\"left\"><font color=\"blue\">Your shipping address has been updated.</font></div>");
				body.append("</TD>");
				body.append("</TR>");
				
				body.append("</form>");
				
				body.append("</TABLE>");
			}
			
			cart = ((CartOfItems)session.getAttribute(Constants.cartAttributeName));
			if (cart != null)
				dvds = cart.getAllDvds();
			
			body.append("<div>");
			//print out the current cart, with the prices and total cost
			body.append(printCartWithPrices(dvds));
			
			if (getTotalQuantity(dvds) > 0 && customerInfoValid)
			{
				body.append("<form name=\"purchaseForm\" action=\"Confirmation\" method=\"POST\">");
				body.append("<input align=\"right\" type=\"image\" name=\"PurchaseButton\" src=\"../images/Purchase.png\">");
				body.append("</div>");
			}
			else if (!customerInfoValid)
			{
				body.append("<h4><font color=\"red\">You need to fix your information before " +
						"you can make a purchase.</h4>");
			}
			else
			{
				body.append("You have not selected anything to purchase.");
			}
			
			
			
						
		} catch (Exception e) 
		{
			out.println("Exception: " + e.getMessage());
			e.printStackTrace();
		}		
		
		out.print(Template.getTemplateHTML("Check Out", body.toString(),
				Constants.noCheckoutButton, session  ));
	}
	
	private String printCartWithPrices(ArrayList<DVD> dvds)
	{
		StringBuffer buf = new StringBuffer();
		
		//buf.append("<form name=\"cartForm\" action=\"DvdProcessor\" method=\"GET\">");
		//out.println("<div align=\"left\"><br>");
		
		//making table
	
		buf.append("<div><TABLE bgcolor=\"#FFFFFF\" border=1 bordercolorlight=\"#C0C0C0\" bordercolordark=\"#808080\">");
		
		buf.append("<TR valign=top>");	
	
		buf.append("<TD width=150><div class=\"wpmd\">");
		buf.append("<div>");
		buf.append("<B>TITLE</B>");
		buf.append("</div>");
		buf.append("</TD>");		
		
		buf.append("<TD width=100><div class=\"wpmd\">");
		buf.append("<div>");
		buf.append("<B>YEAR</B>");
		buf.append("</div>");
		buf.append("</TD>");
		
		buf.append("<TD width=150><div class=\"wpmd\">");
		buf.append("<div>");
		buf.append("<B>DIRECTOR</B>");
		buf.append("</div>");
		buf.append("</TD>");
		
		buf.append("<TD width=150><div class=\"wpmd\">");
		buf.append("<div>");
		buf.append("<B>QUANTITY</B>");
		buf.append("</div>");
		buf.append("</TD>");
				
		buf.append("<TD width=150><div class=\"wpmd\">");
		buf.append("<div>");
		buf.append("<B>PRICE</B>");
		buf.append("</div>");
		buf.append("</TD>");
		buf.append("</TR>");
		
		Price totalPrice = new Price(0);
		
		for (int i = 0; i < dvds.size(); i++)
		{
			//title
			buf.append("<TR valign=top>");
			buf.append("<TD width=150><div class=\"wpmd\">");
			buf.append("<div>");
			buf.append( dvds.get(i).getTitle() );
			buf.append("</div>");
			buf.append("</TD>");
			
			//year
			buf.append("<TD width=100><div class=\"wpmd\">");
			buf.append("<div>");
			buf.append( dvds.get(i).getYear() );
			buf.append("</div>");
			buf.append("</TD>");
			
			//director's name
			buf.append("<TD width=150><div class=\"wpmd\">");
			buf.append("<div>");
			buf.append( dvds.get(i).getDirectorName() );
			buf.append("</div>");
			buf.append("</TD>");
			
			// quantity
			buf.append("<TD width=150><div class=\"wpmd\">");
			buf.append("<div>");
			buf.append(dvds.get(i).getQuantity() );
			buf.append("</div>");
			buf.append("</TD>");
			totalPrice.addPrice( dvds.get(i).getPrice() );
			
			// price
			buf.append("<TD width=150><div class=\"wpmd\">");
			buf.append("<div>");
			buf.append( dvds.get(i).getPrice().toString() );
			buf.append("</div>");
			buf.append("</TD>");
			
			buf.append("</TR>");
		}
		
		buf.append("<TR valign=top>");
		buf.append("</TR>");
		buf.append("<TR valign=top>");
		buf.append("<TD width=150><div class=\"wpmd\">");
		buf.append("</TD>");
		buf.append("<TD width=100><div class=\"wpmd\">");
		buf.append("</TD>");
		buf.append("<TD width=100><div class=\"wpmd\">");
		buf.append("</TD>");
		buf.append("<TD width=150><div class=\"wpmd\">");
		buf.append("<B>TOTAL PRICE:</B>");
		buf.append("</TD>");
		buf.append("<TD width=200><div class=\"wpmd\">");
		buf.append("<B><font color=\"green\">" + totalPrice + "</font></B>" );
		buf.append("</TD>");
		buf.append("</TR>");
		
		buf.append("</TABLE>");

		//buf.append("</form>");
		
		return buf.toString();
	}
	
	private static boolean isNumber(String number)
	{
		try 
		{
		
			int num = Integer.parseInt(number);
		}
		catch(NumberFormatException e)
		{
			return false;
		}
		return true;
	}
	
	private int getTotalQuantity(ArrayList<DVD> dvds)
	{
		int total = 0;
		
		for (int i = 0; i < dvds.size(); i++)
		{
			total += dvds.get(i).getQuantity();
		}
		
		return total;
	}
}
